﻿using System;
using System.Collections.Generic;
using System.Text;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// 类型转换接口
    /// </summary>
    public interface ITypeConverter
    {
        /// <summary>
        /// 转换器类型
        /// </summary>
        PrimitiveDataTypes ConverterType { get; }

        /// <summary>
        /// 将字符串转换为值类型数据,包括枚举
        /// </summary>
        /// <param name="options">类型转换选项参数</param>
        /// <param name="value">要转换的值</param>
        /// <returns>转换后的值</returns>
        object ConvertTo(ITypeConverterOptions options, object value);

        /// <summary>
        /// 转换数据到
        /// </summary>
        /// <param name="options">类型转换选项参数</param>
        /// <param name="value">要转换的值</param>
        /// <param name="result">转换后的值,存放在object中,如果转换失败为目标类型的默认值</param>
        /// <returns>转换成功返回true,失败返回false</returns>
        bool TryConvertTo(ITypeConverterOptions options, object value, out object result);

    }

    /// <summary>
    /// 类型转换选项参数
    /// </summary>
    public class TypeConverterOptions : ITypeConverterOptions
    {
        /// <summary>
        /// 枚举类型名称
        /// </summary>
        public string SourceEnumTypeName { get; set; } = null;

        /// <summary>
        /// 目标枚举类型名称
        /// </summary>
        public string TargetEnumTypeName { get; set; } = null;

        /// <summary>
        /// 值中数字基数(value是何种进制的字符串),必须是2,8,10,16
        /// </summary>
        public byte FromBase { get; set; } = 10;

        /// <summary>
        /// 字符串中数值样式[数字样式为NumberStyles值之一，日期时间为DateTimeStyles值之一,默认null为不使用样式]
        /// </summary>
        public object Style { get; set; } = null;

        /// <summary>
        /// 一个提供区域性特定的格式设置信息的对象
        /// </summary>
        public IFormatProvider FormatProvider { get; set; } = null;

        /// <summary>
        /// 自定义转换器
        /// </summary>
        public ICustomerConverter Converter { get; set; } = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        public TypeConverterOptions()
        {

        }
    }

    /// <summary>
    /// 类型转换选项参数接口
    /// </summary>
    public interface ITypeConverterOptions
    {
        /// <summary>
        /// 原始枚举类型名称
        /// </summary>
        string SourceEnumTypeName { get; }

        /// <summary>
        /// 目标枚举类型名称
        /// </summary>
        string TargetEnumTypeName { get; }

        /// <summary>
        /// 值中数字基数(value是何种进制的字符串),必须是2,8,10,16
        /// </summary>
        byte FromBase { get; }

        /// <summary>
        /// 字符串中数值样式[数字样式为NumberStyles值之一，日期时间为DateTimeStyles值之一,默认null为不使用样式]
        /// </summary>
        object Style { get; }

        /// <summary>
        /// 一个提供区域性特定的格式设置信息的对象
        /// </summary>
        IFormatProvider FormatProvider { get; }

        /// <summary>
        /// 自定义转换器
        /// </summary>
        ICustomerConverter Converter { get; }
    }

    /// <summary>
    /// 自定义转换器
    /// </summary>
    public interface ICustomerConverter
    {
        /// <summary>
        /// 将字符串转换为值类型数据,包括枚举
        /// </summary>
        /// <param name="options">类型转换选项参数</param>
        /// <param name="value">要转换的值</param>
        /// <param name="valueType">值类型</param>
        /// <returns>转换后的值</returns>
        object ConvertTo(ITypeConverterOptions options, object value, PrimitiveDataTypes valueType);

        /// <summary>
        /// 转换数据到
        /// </summary>
        /// <param name="options">类型转换选项参数</param>
        /// <param name="value">要转换的值</param>
        /// <param name="valueType">值类型</param>
        /// <param name="result">转换后的值,存放在object中,如果转换失败为目标类型的默认值</param>
        /// <returns>转换成功返回true,失败返回false</returns>
        bool TryConvertTo(ITypeConverterOptions options, object value, PrimitiveDataTypes valueType, out object result);
    }
}
